﻿using Crm.Infrastructure.IOC;
using Crm.Service.Instance;
using CRM.Infrastructure.Attr;
using CRM.Infrastructure.Dto.Response.Dictionary;
using CRM.Infrastructure.Dto.Response;
using CRM.Infrastructure.IOC;
using CRM.Service.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CRM.Infrastructure.Dto.Response.product;
using Microsoft.EntityFrameworkCore;
using CRM.Infrastructure.Dto.Request.Dictionary;
using CRM.Infrastructure.EFCore.Mysql;
using CRM.Infrastructure.Tools;
using CRM.Infrastructure.Dto.Request.products;
using CRM.Infrastructure.Dto.Response.Org;
using MySqlX.XDevAPI.Common;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace CRM.Service.Instance
{
    [Inject_]
    public class Products_Service:Base_Service,I_Products_Service
    {
        private readonly Products_IOC _products_IOC;
        private readonly Login_IOC _login_IOC;

        public Products_Service(Products_IOC products_IOC, Login_IOC login_IOC)
        {
            _products_IOC = products_IOC;
            _login_IOC = login_IOC;

        }
        /// <summary>
        /// 获取产品类型列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<Api_Response_Dto> Get_Products_Types(int page = 1, int limit = 10, string key = "")
        {
            var iq = _products_IOC._product_Types_EFCore.QueryAll(out int total, page, limit,
                 false, o => o.TypeCreateTime, d => d.TypeName!.Contains(key));
            
            var data = await iq.Select(d => new Product_Type_Response_Dto
            {
                id = d.TypeId,
                name = d.TypeName,
                datetime = d.TypeCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                count=0
            }).ToListAsync();
            var count = await _products_IOC._products_EFCore.QueryAll(d => data.Select(e => e.id).Contains(d.TypeId)).ToListAsync();
            data.ForEach(d =>
            {
                foreach (var i in count)
                {
                    if (i.TypeId == d.id)
                    {
                        d.count += 1;
                    }
                }
            });


            return Result(1, "ok", new
            {
                total,
                data,
            });

        }
        /// <summary>
        /// 新增产品类别
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Api_Response_Dto> Add_Products_Types(string name)
        {
            ProductType productType = new ProductType()
            {
                TypeId = Config.GUID_1(),
                TypeName = name,
                TypeCreateTime = DateTime.Now,

            };
            _products_IOC._product_Types_EFCore.Add(productType);
            var result = await _products_IOC._product_Types_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Details_Products(string id, string key = "")
        {
                var iq = _products_IOC._products_EFCore.QueryAll( d => d.TypeId==id && d.ProductName.Contains(key));
                

                var data = await iq.Select(d => new Product_Response_Dto
                {
                    id = d.ProductId,
                    name = d.ProductName,
                    datetime = d.ProductCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                    price = d.Price,
                    img=d.ProductImg,
                    expalain=d.ProductExplain,
                    list=d.ProductList,
                    enddatetime=d.EndDatetime,
                    startdatetime = d.StartDatetime,
                    discountprice = d.DiscountPrice,
                }).ToListAsync();
            return Result(1, "ok", new
            {
                data,
            });
        }
        public async Task<Api_Response_Dto> Details_Products_single(string id)
        {
            var iq = _products_IOC._products_EFCore.QueryAll(d => d.ProductId == id);

            var data = await iq.Select(d => new Product_Response_Dto
            {
                id = d.ProductId,
                name = d.ProductName,
                datetime = d.ProductCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                price = d.Price,
                img = d.ProductImg,
                expalain = d.ProductExplain,
                list = d.ProductList,
                discountprice= d.DiscountPrice,
                startdatetime=d.StartDatetime,
                enddatetime=d.EndDatetime,
            }).ToListAsync();
            return Result(1, "ok", new
            {
                data,
            });
        }
        
        /// <summary>
        /// 更新产品图片 URL
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="imageUrl"></param>
        /// <returns></returns>
        public async Task<Api_Response_Dto> UpdateProductImageUrl(string productId, string imageUrl)
        {
            var product = _products_IOC._products_EFCore.QueryAll(d=>d.ProductId== productId).Single();
            if (product == null)
                return Result(0); ;

            product.ProductImg = "http://localhost:5293"+imageUrl;
            _products_IOC._products_EFCore.Update(product);

            var result = await _products_IOC._products_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Update_Product(Product_Response_Dto dto)
        {
            var iq = _products_IOC._products_EFCore.QueryAll(d => d.ProductId == dto.id).Single();
            iq.ProductName = dto.name;
            iq.Price = dto.price;
            iq.ProductExplain= dto.expalain;
            if (dto.enddatetime == Convert.ToDateTime("1970 - 01 - 01 00:00:00"))
            {
                iq.EndDatetime = null;
                iq.StartDatetime = null;
            }
            else
            {
                iq.EndDatetime = dto.enddatetime;
                iq.StartDatetime = dto.startdatetime;
            }
            
            iq.DiscountPrice= dto.discountprice;
            iq.ProductImg = dto.img;
            _products_IOC._products_EFCore.Update(iq);
            var result = await _products_IOC._products_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Update_Product_Type(string id, string name)
        {
            var iq = _products_IOC._product_Types_EFCore.QueryAll(d => d.TypeId == id).Single();
            iq.TypeName = name;
            _products_IOC._product_Types_EFCore.Update(iq);
            var result = await _products_IOC._product_Types_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Delete_Product(string id)
        {
            var iq = _products_IOC._products_EFCore.QueryAll(d => d.ProductId == id).Single();
            _products_IOC._products_EFCore.Delete(iq);
            var result = await _products_IOC._products_EFCore.SaveChangesAsync();
            return Result(result);
        }
        public async Task<Api_Response_Dto> Delete_Product_Type(string id)
        {
            var iq = _products_IOC._product_Types_EFCore.QueryAll(d => d.TypeId == id).Single();
            _products_IOC._product_Types_EFCore.Delete(iq);
            var result = await _products_IOC._product_Types_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Add_product(Product_Response_Dto dto)
        {
            if (dto.enddatetime == Convert.ToDateTime("1970 - 01 - 01 00:00:00"))
            {
                dto.enddatetime = null;
                dto.startdatetime = null;
            }
            Product product = new Product()
            {
                ProductId = Config.GUID_1(),
                ProductName = dto.name,
                Price = dto.price,
                ProductImg = dto.img,
                TypeId = dto.typeid,
                ProductExplain = dto.expalain,
                ProductList=0,
                EndDatetime=Convert.ToDateTime(dto.enddatetime),
                StartDatetime=Convert.ToDateTime(dto.startdatetime),
                DiscountPrice=dto.discountprice,
            };
            _products_IOC._products_EFCore.Add(product);
            var result = await _products_IOC._products_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> add_upload(string imageUrl)
        {
            var iq = _products_IOC._products_EFCore.QueryAll();
            var data = await iq.Select(d => new Product_Response_Dto
            {
                id = d.TypeId,
                img=imageUrl
            }).ToListAsync();

            var result = await _products_IOC._products_EFCore.SaveChangesAsync();
            return Result(1, "ok", "http://localhost:5293" + imageUrl);
        }
        public async Task<Api_Response_Dto> Get_Products(string key = "", int page = 1, int limit = 10)
        {
            var iq = _products_IOC._products_EFCore.QueryAll(out int total, page, limit,
                 false, d => d.ProductCreateTime, d => d.ProductName!.Contains(key));
            var data = await iq.Select(d => new Product_Response_Dto
            {
                id = d.ProductId,
                    name = d.ProductName,
                    datetime = d.ProductCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
                    price = d.Price,
                    img=d.ProductImg,
                    expalain=d.ProductExplain,
                    list=d.ProductList,
                    enddatetime2=d.EndDatetime.Value.ToString("yyyy-MM-dd"),
                    startdatetime2 = d.StartDatetime.Value.ToString("yyyy-MM-dd"),
                enddatetime = d.EndDatetime,
                startdatetime = d.StartDatetime,
                discountprice = d.DiscountPrice,
                    typeid = d.TypeId,
                    salesvolume=d.ProductSalesVolume
            }).ToListAsync();

            return Result(1, "ok", new
            {
                total,
                data,
            });

        }
        public async Task<Api_Response_Dto> Get_Products_Types_Products()
        {
            var iq = _products_IOC._product_Types_EFCore.QueryAll();
            var data = await iq.Select(d => new Product_Type_Response_Dto
            {
                id = d.TypeId,
                name = d.TypeName,
                datetime = d.TypeCreateTime!.Value.ToString("yyyy-MM-dd HH:mm:ss"),
            }).ToListAsync();

            return Result(1, "ok", new
            {
                data,
            });

        }
        
        public async Task<Api_Response_Dto> Update_List(string id)
        {
            var iq = _products_IOC._products_EFCore.QueryAll(d => d.ProductId == id).Single();
            if (iq.ProductList==0)
            {
                iq.ProductList = 1;
                _products_IOC._products_EFCore.Update(iq);
                var result = await _products_IOC._products_EFCore.SaveChangesAsync();
                return Result(result);
            }
            else if (iq.ProductList==1)
            {
                iq.ProductList = 0;
                _products_IOC._products_EFCore.Update(iq);
                var result = await _products_IOC._products_EFCore.SaveChangesAsync();
                return Result(result);
            }
            return Result(0);
        }
        public async Task<Api_Response_Dto> Add_Setmenu(Product_Response_Dto[] dto,string name,int list)
        {
            Setmenu setmenu = new Setmenu()
            {
                SId = Config.GUID_1(),
                SName = name,
                SMoney = 0,
                SCreateTime = DateTime.Now,
                SList = list,
            };
            List<SetmenuProduct> setmenuProducts= new List<SetmenuProduct>();
            foreach (var i in dto)
            {
                setmenuProducts.Add( new SetmenuProduct()
                {
                    SpId = Config.GUID_1(),
                    SpSid = setmenu.SId,
                    SpPid = i.id,
                    SpCreateTime = DateTime.Now,
                    SpMoney = i.money,
                    SpSum = i.sum,
                    SpSumMoney = i.money * i.sum,
                    SpImg = i.img,
                });
            }
            foreach (var i in setmenuProducts)
            {
                setmenu.SMoney += i.SpSumMoney;
            }
            _products_IOC._setmenu_EFCore.Add(setmenu);

            _products_IOC._setmenu_EFCore.SaveChanges();
            _products_IOC._setmenu_product_EFCore.AddRange(setmenuProducts);
            var result= await _products_IOC._setmenu_product_EFCore.SaveChangesAsync();
            return Result(result);  
        }
        public async Task<Api_Response_Dto> Get_Setmenu(string key, int page, int limit)
        {
            var iq = _products_IOC._setmenu_EFCore.QueryAll(out int total, page, limit,
                 false, d => d.SCreateTime, d => d.SName!.Contains(key));
            var data = await iq.Select(d => new Setmenu_Response_Dto
            {
                id = d.SId,
                name = d.SName,
                createtime = d.SCreateTime,
                list = d.SList,
                money = d.SMoney,
            }).ToListAsync();

            return Result(1, "ok", new
            {
                total,
                data,
            });
        }
        public async Task<Api_Response_Dto> Get_Setmenu_product(string id)
        {
            var iq = _products_IOC._setmenu_product_EFCore.QueryAll(d=>d.SpSid==id);
            var data = await iq.Select(d => new SetmenuProduct
            {
                SpId = d.SpId,
                SpPid = d.SpPid,
                SpSid = d.SpPid,
                SpCreateTime = d.SpCreateTime,
                SpMoney = d.SpMoney,
                SpSum = d.SpSum,
                SpSumMoney = d.SpSumMoney,
                SpImg = d.SpImg,
            }).ToListAsync();
            var name=_products_IOC._products_EFCore.QueryAll();
            data.ForEach(d =>
            {
                d.SpPid = name.Where(e => e.ProductId == d.SpPid).SingleOrDefault()?.ProductName;
            });
            return Result(1, "ok", new
            {
                data,
            });
        }
        
        public async Task<Api_Response_Dto> Del_Setmenu(string id)
        {
            var iq=_products_IOC._setmenu_EFCore.QueryAll(d=>d.SId==id).Single();
            var iq2=_products_IOC._setmenu_product_EFCore.QueryAll(d=>d.SpSid==id).ToList();
            _products_IOC._setmenu_EFCore.Delete(iq);
            _products_IOC._setmenu_product_EFCore.DeleteRange(iq2);
            _products_IOC._setmenu_product_EFCore.SaveChanges();
            var result= await _products_IOC._setmenu_EFCore.SaveChangesAsync();
            return Result(result);
        }

        public async Task<Api_Response_Dto> Update_Setmenu(Product_Response_Dto[] dto,string id,string name ,int list)
        {
            var iq = _products_IOC._setmenu_EFCore.QueryAll(d => d.SId == id).Single();
            var iq2= _products_IOC._setmenu_product_EFCore.QueryAll(d => d.SpSid == id).ToList();
            _products_IOC._setmenu_product_EFCore.DeleteRange(iq2);
            _products_IOC._setmenu_product_EFCore.SaveChanges();
            iq.SName = name;
            iq.SList = list;
            iq.SMoney = 0;
            List<SetmenuProduct> setmenuProducts = new List<SetmenuProduct>();
            foreach (var i in dto)
            {
                setmenuProducts.Add(new SetmenuProduct()
                {
                    SpId = Config.GUID_1(),
                    SpSid = iq.SId,
                    SpPid = i.id,
                    SpCreateTime = DateTime.Now,
                    SpMoney = i.money,
                    SpSum = i.sum,
                    SpSumMoney = i.money * i.sum,
                    SpImg = i.img,
                });
            }
            foreach (var i in setmenuProducts)
            {
                iq.SMoney += i.SpSumMoney;
            }
            _products_IOC._setmenu_EFCore.Update(iq);

            _products_IOC._setmenu_EFCore.SaveChanges();
            _products_IOC._setmenu_product_EFCore.AddRange(setmenuProducts);
            var result = await _products_IOC._setmenu_product_EFCore.SaveChangesAsync();
            return Result(result);

        }



    }
}
